/* eslint-disable */
/**
 * 折线图、柱状图、面积图、点状图、堆叠折现图、堆叠面积图、堆叠柱状图
 * XYAxisChartsC (reactCharts)
 * @author zxy
 * @date  2020-09-08
 */
import accounting from 'accounting';
import { Spin } from 'antd';
import ReactEcharts from 'echarts-for-react';
import _ from 'lodash';
import PropTypes from 'prop-types';
import React from 'react';

import Color from '../../../css/colors';
import { NoDataC } from '../../other';
import { constant } from '@/src/components/echarts/linkageCharts/constant';

class XYAxisChartsC extends React.Component {
  // 入参默认值设置
  static defaultProps = {
    xAxis: undefined,
    series: undefined,
    type: 'line', // 默认折线图
    height: '100%', // 图形高度默认为父节点的100%
    width: '100%', // 图形宽度默认为父节点的100%
    dataZoom: false, // 默认无横向滚动轴
    colors: Color.echart, // 默认系统色
    title: '', // 标题默认为空
    yAxisUnit: [], // 默认纵轴上无单位（从左向右，每一项用字符串数据表示）
    yAxisFormat: [], // 默认纵轴数据显示无格式处理（从左向右，每一项用func表示，如[value=>parseInt(value)}, value=>value+'%',...]）
    yAxisRange: [], // 默认使用组件内部min max策略
    boundaryGap: true, // 默认坐标轴两边留白
    lableRotate: 0, // 默认横轴字体不旋转
    isAbbreviate: false, // 默认不缩略展示
    showBorder: false, // 默认不展示外边框
    toolTipFormat: undefined, // 默认按自定义的提示信息样式展示
    toolTipDataFormat: [], // 默认提示信息中的数据无任何处理
    hasYAxisPosi: false, // 默认不在图例中显示“左右”
    gridLeft: 60, // 默认左轴距离左侧距离为60
    gridRight: 60, // 默认右轴距离右侧距离为60
    seriesLabelDataFormat: [], // 默认不展示图形上的文本标签
    percentStyle: [], // 默认不必遵守百分比规则
    markArea: undefined, // 默认不设置区域样式
    barMaxWidth: 20, // 默认柱状图最大宽度是20
    legentAbbreviate: false, // 默认图例不缩略展示
    debtAndProfit: false, // 默认无收益&负债类型的样式（红绿）
    click: () => {}, // 默认不响应click事件
    mouseOver: () => {}, // 浮上去事件
    mouseOut: () => {}, // 浮出去事件
    isShowLegent: true, // 默认展示图例
    isShowTooltip: true, // 默认展示tooltip
    legendSelect: undefined, // 默认初始不设置图例状态
    thousandthStyle: false, // 默认tooltip中的数字不千分位展示
    tooltipValueFix: undefined, // 默认tooltip中的数字无精度
    xPosition: 'bottom', // x坐标轴的位置
    legendType: 'plain', // 图例的类型。'plain'：普通图例。'scroll'：可滚动翻页的图例。当图例数量较多时可以使用。
    isClickGrid: false, // 是否点击的是 点 或者 柱形所在的y轴 ；这个可以用于数据很小 点不到的情况
    isMarkPoint: false, // 是否显示最大最小值
    cordonConfig: undefined, // 警戒线，存在则和最大值比较大于则为最大值
    axisLabelFormatter: undefined, // Formatter x轴的字Formatter函数
    axisLabelMargin: 6, // x轴的字距离x轴的距离 默认6
    legendBottom: 15, // 图例距离底的距离 默认15
    isResponsiveHeight: false, // 是否是响应式高度
  };

  debtAndProfitColor = Color.debtAndProfit.background; // type为收益负债模式时，固定显示的颜色

  constructor(props) {
    super(props);

    this.state = {
      chartHeight: props.height === 'auto' ? 200 : props.height, // 根据当前图例数据量的多少自动设置图形高度
    };
  }

  shouldComponentUpdate(nextProps, nextState) {
    if (JSON.stringify(this.props) === JSON.stringify(nextProps)) {
      return false;
    }
    return true;
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    if (prevProps.xAxis === undefined && prevProps.series === undefined && this.props.xAxis && this.props.series) {
      this.echartsIsInit = false;
    }
  }

  SERIESLABELWidth = 40; // 常量，图形上文本标签宽度显示上限

  // 返回option
  getOption = (legend, yAxis, series, dataZoom) => {
    const {
      colors,
      title,
      xAxis,
      toolTipFormat,
      yAxisUnit,
      boundaryGap,
      showBorder,
      markArea,
      type,
      lableRotate,
      toolTipDataFormat,
      hasYAxisPosi,
      gridLeft,
      gridRight,
      isAbbreviate,
      legentAbbreviate,
      isShowLegent,
      isShowTooltip,
      legendSelect,
      thousandthStyle,
      tooltipValueFix,
      xPosition,
      colorType,
      legendType,
      axisLabelFormatter,
      axisLabelMargin,
      legendBottom,
    } = this.props;

    let hasTwoxAxis = false;
    if (xAxis && xAxis.length == 2 && Array.isArray(xAxis[0]) && Array.isArray(xAxis[1])) {
      hasTwoxAxis = true;
      series[1].xAxisIndex = 1;
    }
    let colorss;
    switch (colorType) {
      case 'darkBlue':
        colorss = Color.darkBlueEchart;
        break;
      case 'red':
        colorss = Color.redEchart;
        break;
      default:
        colorss = colors;
    }
    if (this.props.cordonConfig) {
      series.map((item, index) => {
        if (index === 0) {
          item.markLine = {
            symbol: ['none', 'none'], // ['none']表示是一条横线；['arrow', 'none']表示线的左边是箭头，右边没右箭头；['none','arrow']表示线的左边没有箭头，右边有箭头
            label: {
              position: 'start', // 将警示值放在哪个位置，三个值“start”,"middle","end" 开始 中点 结束
            },
            data: [
              {
                silent: false, // 鼠标悬停事件 true没有，false有
                lineStyle: {
                  // 警戒线的样式 ，虚实 颜色
                  type: 'dotted', // 样式  ‘solid’和'dotted'
                  color: '#FA3934',
                  width: 3, // 宽度
                },
                yAxis: this.props.cordonConfig?.cordonValue, // 警戒线的标注值，可以有多个yAxis,多条警示线 或者采用 {type : 'average', name: '平均值'}，type值有 max min average，分为最大，最小，平均值
              },
            ],
          };
        }
      });
    }
    return {
      // 调色盘颜色列表
      color: colorss,
      backgroundColor: colorType == 'red' ? Color.echartItems.bgColorR : colorType == 'darkBlue' ? Color.echartItems.bgColorD : Color.echartItems.bgColor, // echarts整个画布的背景色
      // 主标题和副标题
      title: {
        show: !!title,
        left: '20',
        top: showBorder ? 30 : 20,
        text: title,
        textStyle: {
          color: Color.echartItems.title,
          fontSize: 14,
          fontWeight: 'normal',
          lineHeight: 20,
        },
      },
      // 鼠标移动上去提示信息
      tooltip: {
        trigger: 'axis',
        show: isShowTooltip,
        axisPointer: {
          type: 'line', // tooltip展示十字型
          crossStyle: {
            color: Color.echartItems.tooltipCross,
          },
          label: {
            show: false,
            backgroundColor: Color.echartItems.tooltipBg, // 坐标轴指示器的背景颜色
            color: Color.echartItems.tooltipLabel,
            padding: [7, 7, 5, 7],
          },
        },
        formatter:
          toolTipFormat ||
          ((params) => {
            let str = `<div style="color:${Color.echartItems.tooltipLabel}">`;
            str += `<div style="margin-bottom:12px">${params[0].name}</div>`;

            params.map((item, index) => {
              let value = item.value == null || item.value == undefined ? '--' : item.value;
              // 根据seriesName，去series匹配，找出对应的yAxisIndex
              let yAxisIndex = -1;
              let toFixed;
              series.forEach((element) => {
                if (element.name === item.seriesName) {
                  yAxisIndex = element.yAxisIndex;
                  toFixed = element.toFixed; // 每个选项展示格式 保留小数位
                }
              });

              if (thousandthStyle) {
                // 需要千分位展示
                if (typeof value == 'number') {
                  // 转换前必须是数字类型，（排除null，undefined，空字符串）
                  value = accounting.formatNumber(Number(value), tooltipValueFix);
                }
              }

              if (toolTipDataFormat[yAxisIndex]) {
                value = toolTipDataFormat[yAxisIndex](value);
              }
              if (toFixed && typeof value == 'number') {
                // 每个选项展示格式 保留小数位
                // 转换前必须是数字类型，（排除null，undefined，空字符串）
                value = accounting.formatNumber(Number(value), toFixed);
              }

              str += `<div style="display:flex;align-items:center;margin-top:8px">
                      <div style="border:1px solid rgb(255,255,255);width:10px;height:10px;border-radius:50%;background-color:${item.color};margin-right:8px"></div>
                      ${item.seriesName}： ${value}
                    </div>`;
            });
            str += '</div>';
            return str;
          }),
        padding: [12, 12, 12, 12],
        confine: true,
        backgroundColor: Color.echartItems.tooltipBgColor,
        extraCssText: `box-shadow: 0px 2px 12px 0px ${Color.echartItems.tooltipBgShadow};border-radius: 4px;opacity: 0.65;font-size: 12px;font-family: PingFangSC-Regular, PingFang SC;font-weight: 400;`,
      },
      // 图例
      legend: {
        type: legendType,
        // pageIcons: {
        //   horizontal: [`image://${leftIcon}`, `image://${rightIcon}`]
        // },
        // pageIconSize: [15,20],
        show: isShowLegent ? legend.length > 1 : false, // 只有一项时，隐藏
        data: legend,
        selected: legendSelect,
        bottom: legendBottom,
        right: 20,
        left: legendType == 'scroll' ? 20 : null,
        textStyle: {
          color: Color.echartItems.legend,
          fontSize: 12,
        },
        itemWidth: 20,
        itemHeight: 14,
        borderRadius: [0, 0, 0, 0],
        formatter: (name) => {
          // 图例缩略展示
          if (legentAbbreviate && name && name.length > 5) {
            return `${name.substring(0, 5)}...`;
          }
          if (hasYAxisPosi) {
            // 图例显示左右轴
            // 根据name，去series匹配，找出对应的yAxisIndex
            let yAxisIndex = -1;
            series.forEach((element) => {
              if (element.name === name) {
                yAxisIndex = element.yAxisIndex;
              }
            });
            if (yAxisIndex === 0) {
              return `${name}(左)`;
            }
            return `${name}(右)`;
          }
          return name;
        },
      },
      // 直角坐标系内绘图网格
      grid: {
        left: gridLeft,
        right: gridRight,
        top: showBorder ? (title ? (yAxisUnit.length > 0 ? 100 : 80) : yAxisUnit.length > 0 ? 76 : 56) : title ? (yAxisUnit.length > 0 ? 90 : 70) : yAxisUnit.length > 0 ? 50 : 30, // 根据是否有边框、title、坐标轴显示名称动态调整
        bottom: lableRotate === 0 ? (legend.length > 1 ? (dataZoom ? 120 : 62) : dataZoom ? 100 : 37) : legend.length > 1 ? (dataZoom ? 140 : 95) : dataZoom ? 120 : 57,
      },
      // 横轴
      xAxis: [
        {
          type: 'category',
          boundaryGap: markArea ? false : type === 'area' || type === 'areaStack' ? false : boundaryGap, // 标记横轴左右是否有空隙
          data: hasTwoxAxis ? xAxis[0] : xAxis,
          axisLine: {
            lineStyle: {
              color: Color.echartItems.xAxisLine,
            },
          },
          axisTick: {
            show: false,
          },
          position: xPosition,
          axisLabel: {
            color: isAbbreviate ? Color.echartItems.rotateXaxisLabel : Color.echartItems.xAxisLabel,
            margin: axisLabelMargin, // 与横轴的距离
            fontSize: 12,
            rotate: isAbbreviate ? 30 : lableRotate, // 字体旋转角度
            formatter: axisLabelFormatter
              ? axisLabelFormatter
              : (value, index) => {
                  // 10个字一行，多了换行展示
                  if (isAbbreviate) {
                    if (value.length > 5) {
                      return `${value.substring(0, 5)}...`;
                    }
                    return value;
                  }
                  const totalRow = Math.ceil(value.length / 10);
                  let str = '';
                  for (let i = 0; i < totalRow; i++) {
                    if (i < totalRow - 1) {
                      str += `${value.substring(10 * i, 10 * (i + 1))}\n`;
                    } else {
                      str += `${value.substring(10 * i, value.length)}`;
                    }
                  }
                  return str;
                },
          },
        },
        {
          type: 'category',
          show: false,
          data: hasTwoxAxis ? xAxis[1] : xAxis,
        },
      ],
      // 纵轴
      yAxis,
      // 横向滚动条
      dataZoom: dataZoom
        ? [
            {
              ...dataZoom,
              bottom: legend.length > 1 ? 45 : 20,
              height: 40,
              left: 20,
              right: 20,
              handleColor: colorType == 'red' ? Color.echartItems.dataZoomHandBgR : colorType == 'darkBlue' ? Color.echartItems.dataZoomHandBgD : Color.echartItems.dataZoomHandBg, // 滑动图标的颜色
              borderColor: colorType == 'red' ? Color.echartItems.dataZoomBgR : colorType == 'darkBlue' ? Color.echartItems.dataZoomBgD : Color.echartItems.dataZoomBorderBg, // 边框颜色
              backgroundColor: colorType == 'red' ? Color.echartItems.dataZoomBgR : colorType == 'darkBlue' ? Color.echartItems.dataZoomBgD : Color.echartItems.dataZoomBg, // 滚动条未选中区域的背景颜色
              dataBackground: {
                lineStyle: {
                  color:
                    colorType == 'red' ? Color.echartItems.dataZoomChoosedBgR : colorType == 'darkBlue' ? Color.echartItems.dataZoomChoosedBgD : Color.echartItems.dataZoomShadowBg,
                },
                areaStyle: {
                  color:
                    colorType == 'red' ? Color.echartItems.dataZoomChoosedBgR : colorType == 'darkBlue' ? Color.echartItems.dataZoomChoosedBgD : Color.echartItems.dataZoomShadowBg, // 滚动条数据阴影区域的背景颜色
                  shadowColor:
                    colorType == 'red' ? Color.echartItems.dataZoomChoosedBgR : colorType == 'darkBlue' ? Color.echartItems.dataZoomChoosedBgD : Color.echartItems.dataZoomShadowBg, // 滚动条数据阴影区域的背景颜色
                },
              },
              fillerColor:
                colorType == 'red' ? Color.echartItems.dataZoomChoosedBgR : colorType == 'darkBlue' ? Color.echartItems.dataZoomChoosedBgD : Color.echartItems.dataZoomChoosedBg, // 滚动条选中区域的背景颜色
            },
          ]
        : [],
      // 数据
      series,
    };
  };

  /*
  根据percentStyle输出规则
  legends:若设置了该参数，仅针对该参数中包含的图例进行min和max的计算，若不设置，默认全部计算
  如果纵轴区间为百分数A%~B%，则：
    1）|A-B| / 区间档数 > 1，纵轴显示的百分数仅保留整数；
    2）1 > |A-B| / 区间档数 ≥ 0.1，纵轴显示的百分数保留小数点后1位；
    3）|A-B| / 区间档数 < 0.1，纵轴显示的百分数保留小数点后2位；
  */
  setPercentStyle = (legends) => {
    const yAxisFormat = []; // 根据规则算出的纵轴样式

    this.props.percentStyle.forEach((item, index) => {
      if (item == true) {
        // 找出坐标轴上的最大值和最小值
        let max;
        let min;
        // 如果设置了坐标轴的最大值和最小值，则以设置的值进行计算
        if (this.props.yAxisRange && this.props.yAxisRange[index]) {
          min = this.props.yAxisRange[index][0];
          max = this.props.yAxisRange[index][1];
        } else {
          // 如果未设置坐标轴的最大值和最小值，则自行计算坐标轴的最大值和最小值
          let yAxisSeries = []; // 当前Y轴序号的所有数据
          this.props.series.forEach((data) => {
            if (data.yAxisIndex == index || (index == 0 && data.yAxisIndex == undefined)) {
              if (legends) {
                if (legends.indexOf(data.name) >= 0) {
                  yAxisSeries = yAxisSeries.concat(data.data);
                }
              } else {
                yAxisSeries = yAxisSeries.concat(data.data);
              }
            }
          });
          yAxisSeries.sort((a, b) => a - b); // 数组排序
          if (yAxisSeries.length > 1) {
            min = yAxisSeries[0];
            max = yAxisSeries[yAxisSeries.length - 1];
          }
          if (yAxisSeries.length == 1) {
            min = max = yAxisSeries[0];
          }
        }

        if (min == undefined || max == undefined) {
          yAxisFormat.push(undefined);
        } else {
          min *= 100;
          max *= 100;

          // 根据最大值和最小值计算纵轴需保留的位数
          if ((max - min) / 5 > 1) {
            yAxisFormat.push((value) => `${parseInt(value * 100)}%`);
          }
          if ((max - min) / 5 >= 0.1 && (max - min) / 5 < 1) {
            yAxisFormat.push((value) => `${(value * 100).toFixed(1)}%`);
          }
          if ((max - min) / 5 < 0.1) {
            yAxisFormat.push((value) => `${(value * 100).toFixed(2)}%`);
          }
        }
      } else {
        yAxisFormat.push(undefined);
      }
    });

    return yAxisFormat;
  };

  // 响应图例切换事件
  legendselectchanged = (args) => {
    const { yAxisFormat, series, percentStyle } = this.props;
    // 仅针对设置了百分比的图例进行处理
    if (percentStyle && percentStyle.length > 0) {
      // 根据args.name判断Y轴序号
      const yNum = [];
      for (let i = 0; i < series.length; i++) {
        if (args.name === series[i].name) {
          yNum.push(series[i].yAxisIndex === undefined ? 0 : series[i].yAxisIndex);
          break;
        }
      }

      // 如果对应的Y轴未设置percentStyle，则返回
      if (yNum && yNum.length > 0 && percentStyle[yNum[0]]) {
        // 根据args.selected判断当前Y轴需要纳入统计的name项
        const names = [];
        for (const key in args.selected) {
          if (args.selected[key]) {
            const temp = series.find((item) => item.name == key);
            const index = temp.yAxisIndex;
            if (index === yNum[0] || (yNum[0] == 0 && index == undefined)) {
              names.push(key);
            }
          }
        }
        const calPercent = this.setPercentStyle(names);
        const yAxis = [];

        for (let i = 0; i < this.yAxisNum.length; i++) {
          const element = {
            axisLabel: {
              // Y轴文本样式
              formatter: yAxisFormat[i] === undefined ? (calPercent[i] === undefined ? undefined : calPercent[i]) : yAxisFormat[i], // Y轴lable显示格式
            },
          };
          yAxis.push(element);
        }
        const instance = this.echarts_react.getEchartsInstance(); // echarts实例
        instance.setOption({ yAxis });
      }
    }
  };

  echartsIsInit = false; // 标记echarts图是否已初始化

  // reactEcharts初始化后操作
  initEchartsEvent = (e) => {
    if (!e) return;

    this.echartsIsInit = true; // 标记echarts已初始化完毕
    this.echarts_react = e;
    this.echarts_instance = e.getEchartsInstance(); // echarts实例

    const { seriesLabelDataFormat, gridLeft, gridRight, xAxis, showBorder, title, yAxisUnit, series, height, lableRotate, dataZoom } = this.props;

    // 根据echart的宽度，计算每一项可占宽度，从而判断是否要显示文本标签
    if (seriesLabelDataFormat && seriesLabelDataFormat.length > 0) {
      const seriesNew = [];
      seriesLabelDataFormat.forEach(() => {
        const show = (this.echarts_instance.getWidth() - gridLeft - gridRight) / xAxis.length >= this.SERIESLABELWidth;
        seriesNew.push({ label: { show } });
      });
      this.echarts_instance.setOption({ series: seriesNew });
    }
    const that = this;
    // 柱状图 数据特别少的时候 点击柱子区域 就抛出事件；
    this.echarts_instance.getZr().on('click', (params) => {
      const pointInPixel = [params.offsetX, params.offsetY];
      if (this.echarts_instance.containPixel('grid', pointInPixel)) {
        const dataIndex = this.echarts_instance.convertFromPixel({ seriesIndex: 0 }, [params.offsetX, params.offsetY])[0];
        if (that.props.isClickGrid) {
          this.props.click({ dataIndex });
        }
      }
    });

    // 根据当前图例数据量的多少自动设置图形高度
    if (height === 'auto') {
      const top = showBorder
        ? title
          ? yAxisUnit.length > 0
            ? 80
            : 60
          : yAxisUnit.length > 0
          ? 56
          : 36
        : title
        ? yAxisUnit.length > 0
          ? 70
          : 50
        : yAxisUnit.length > 0
        ? 30
        : 10;
      const bottom = lableRotate === 0 ? (dataZoom ? 100 : 50) : dataZoom ? 120 : 70;
      const right = gridRight;
      const numInLine = parseInt((this.echarts_instance.getWidth() - right) / 100); // 计算一行放几个（默认一个100）
      const lineNum = Math.ceil(series.length / numInLine); // 一共有多少行图例
      const chartBottom = bottom + lineNum * 20; // 计算echart距离bottom的距离
      const chartHeight = top + 200 + chartBottom > 1200 ? 1200 : top + 200 + chartBottom; // 计算echart高度（默认中间主体高度是200，一行图例占高20，最高高度不得超过1200）

      this.echarts_instance.setOption({ grid: { bottom: chartBottom } });
      this.setState({ chartHeight });
    } else {
      this.setState({ chartHeight: height });
    }
  };

  click = (e) => {
    // 抛出点击事件
    if (this.props.isClickGrid) return;
    this.props.click(e);
  };

  render() {
    const {
      series,
      xAxis,
      type,
      width,
      yAxisFormat,
      yAxisUnit,
      percentStyle,
      gridLeft,
      gridRight,
      dataZoom,
      yAxisRange,
      showBorder,
      seriesLabelDataFormat,
      markArea,
      barMaxWidth,
      debtAndProfit,
      height,
      isMarkPoint,
      cordonConfig,
    } = this.props;
    const legend = []; // 图例
    let seriesVals = []; // series
    const yAxis = []; // Y轴
    let zoom; // 横向滚动轴
    const initStatus = series && xAxis; // 标记是否达到初始化状态(true:可以初始化图表，false：还未获取到数据)

    if (initStatus) {
      this.yAxisNum = []; // Y轴序号

      // 根据传参，自动生成series数据和图例数据
      seriesVals =
        series &&
        series.map((item, index) => {
          const yAxisIndex = item.yAxisIndex !== undefined ? item.yAxisIndex : 0; // 默认数据Y轴序号为0

          // 搜集Y轴的所有序号
          if (this.yAxisNum.indexOf(yAxisIndex) < 0) {
            this.yAxisNum.push(yAxisIndex);
          }
          // 搜集图例数据
          legend.push(item.name);

          // 返回series数据
          let data = {
            name: item.name,
            data: item.data,
            yAxisIndex,
            ...item,
          };

          // 若需要设置区域面积
          if (markArea) {
            const mark = [];
            markArea.forEach((element) => {
              mark.push([
                {
                  xAxis: element.range[0],
                  itemStyle: { color: element.color },
                },
                {
                  xAxis: element.range[1],
                },
              ]);
            });
            data.markArea = {
              data: mark,
            };
          }

          let labelShow = true;
          if (this.echartsIsInit && seriesLabelDataFormat && seriesLabelDataFormat.length > 0) {
            labelShow = (this.echarts_instance.getWidth() - gridLeft - gridRight) / xAxis.length >= this.SERIESLABELWidth;
          }

          const echartsType = item.type ? item.type : type; // 图形类型
          switch (echartsType) {
            case 'bar': // 柱状图
              if (debtAndProfit) {
                const newData = [];
                for (let i = 0; i < item.data.length; i++) {
                  const element = item.data[i];
                  newData.push({
                    value: element,
                    itemStyle: {
                      color: element != undefined && element > 0 ? this.debtAndProfitColor[0] : this.debtAndProfitColor[1],
                    },
                  });
                }
                data.data = newData;
              }
              data = {
                ...data,
                type: 'bar',
                barMaxWidth, // 默认最大宽度是20，正常情况下自适应
                label: {
                  show: seriesLabelDataFormat[index] == undefined ? false : labelShow,
                  position: 'top',
                  formatter: seriesLabelDataFormat[index] == undefined ? () => '' : seriesLabelDataFormat[index],
                },
              };
              break;
            case 'area': // 面积图
              data = {
                ...data,
                type: 'line',
                areaStyle: {
                  opacity: 0.3,
                },
                showSymbol: false,
              };
              break;
            case 'point': // 点状图
              data = {
                ...data,
                type: 'line',
                symbol: 'circle',
                symbolSize: 15,
                lineStyle: {
                  opacity: 0,
                },
              };
              break;
            case 'lineStack': // 线性堆叠图
              data = {
                ...data,
                type: 'line',
                stack: '总量',
                showSymbol: false,
              };
              break;
            case 'areaStack': // 面积堆叠图
              data = {
                ...data,
                type: 'line',
                stack: '总量',
                areaStyle: {},
                lineStyle: {
                  width: 0,
                },
                showSymbol: false,
              };
              break;
            case 'barStack': // 柱状堆叠图
              data = {
                ...data,
                type: 'bar',
                barMaxWidth, // 默认最大宽度是20，正常情况下自适应
                stack: '总量',
                label: {
                  show: seriesLabelDataFormat[index] != undefined,
                  position: 'inside',
                  formatter: seriesLabelDataFormat[index] == undefined ? '{c}' : seriesLabelDataFormat[index],
                },
              };
              break;
            default: // 默认是line
              const datas = data.data;
              data = {
                ...data,
                type: 'line',
                showSymbol: datas.length == 1,
                markPoint: isMarkPoint
                  ? {
                      // 自定义最大最小值
                      data: [
                        {
                          type: 'max',
                          name: 'bar-max',
                          itemStyle: { color: '#F4423A' },
                          symbol: `image://${constant.top}`,
                          symbolSize: [16, 16],
                          symbolOffset: [0, -14],
                          label: {
                            color: '#F4423A',
                            offset: [1, -16],
                          },
                        },
                        {
                          type: 'min',
                          name: 'bar-min',
                          itemStyle: { color: '#2FB098' },
                          symbol: `image://${constant.bottom}`,
                          symbolSize: [16, 16],
                          symbolOffset: [0, series[0]?.data?.every((item) => item === series[0]?.data[0]) ? -45 : -14],
                          label: {
                            color: '#2FB098',
                            offset: [1, -16],
                          },
                        },
                      ],
                    }
                  : null,
              };
              break;
          }

          return data;
        });

      let calPercent = [];
      if (percentStyle && percentStyle.length > 0) {
        calPercent = this.setPercentStyle();
      }

      // 根据传参，设计Y轴样式
      for (let i = 0; i < this.yAxisNum.length; i++) {
        const element = {
          name: yAxisUnit === undefined ? undefined : yAxisUnit[i], // 坐标轴显示名称
          type: 'value',
          nameTextStyle: {
            // Y轴名称文本样式
            color: Color.echartItems.title,
            fontSize: 12,
          },
          axisLine: {
            // Y轴轴线样式
            show: false,
            lineStyle: {
              color: Color.echartItems.yAxisLine,
            },
          },
          axisTick: {
            // Y轴间隔小线段样式
            show: false,
          },
          axisLabel: {
            // Y轴文本样式
            color: Color.echartItems.yAxisLabel,
            margin: 4, // 与纵轴的距离
            fontSize: 12,
            formatter: yAxisFormat[i] === undefined ? (calPercent[i] === undefined ? undefined : calPercent[i]) : yAxisFormat[i], // Y轴lable显示格式
          },
          splitNumber: 4, // 坐标轴的分割段数，需要注意的是这个分割段数只是个预估值，最后实际显示的段数会在这个基础上根据分割后坐标轴刻度显示的易读程度作调整
          splitLine: {
            // Y轴分割线样式
            show: i === 0, // 仅在左轴添加分割线
            lineStyle: {
              type: 'dashed',
              color: Color.echartItems.splitLine,
            },
          },
          min: yAxisRange && yAxisRange.length > 0 && yAxisRange[i] ? yAxisRange[i][0] : undefined,
          max: cordonConfig?.cordonValue
            ? (value) => (value.max > cordonConfig?.cordonValue ? (yAxisRange && yAxisRange.length > 0 && yAxisRange[i] ? yAxisRange[i][1] : undefined) : cordonConfig?.cordonValue)
            : yAxisRange && yAxisRange.length > 0 && yAxisRange[i]
            ? yAxisRange[i][1]
            : undefined,
        };

        yAxis.push(element);
      }

      // 根据入参设置横向滚动条
      if (dataZoom) {
        if (typeof dataZoom === 'boolean') {
          zoom = {
            start: 0,
            end: 100,
          };
        } else {
          zoom = {
            startValue: dataZoom.startValue,
            endValue: dataZoom.endValue,
            ...dataZoom,
          };
        }
      }
    }
    return (
      <div style={{ border: showBorder && `1px solid ${Color.echartItems.border}`, width }}>
        <Spin spinning={!initStatus} tip='加载中...'>
          {initStatus ? (
            series.length > 0 && xAxis.length > 0 ? (
              <ReactEcharts
                option={this.getOption(legend, yAxis, seriesVals, zoom)}
                style={{ height: this.props.isResponsiveHeight ? height : this.state.chartHeight, width }}
                // 是否不跟之前设置的 option 进行合并，默认为 false，即合并。
                notMerge
                onEvents={{
                  legendselectchanged: this.legendselectchanged,
                  click: this.click,
                  mouseover: (e) => {
                    this.props.mouseOver(e);
                  },
                  mouseout: (e) => {
                    this.props.mouseOut(e);
                  },
                }}
                ref={this.initEchartsEvent}
              />
            ) : (
              <NoDataC height={height || undefined} />
            )
          ) : (
            // <Empty description='暂无数据' style={{height:this.state.chartHeight,display:'flex',justifyContent:'center',alignItems:'center',flexDirection:'column'}}></Empty>
            <div style={{ height: this.state.chartHeight, width }} />
          )}
        </Spin>
      </div>
    );
  }
}

/*
备注：
  当xAxis和series值为null或undefined时，显示loading状态
  当xAxis和series值为空数组[]时，显示“暂无数据”
  当xAxis和series值为有值的数组时，正常实现图形
*/
XYAxisChartsC.propsTypes = {
  xAxis: PropTypes.array, // 横轴数据（字符串数组）
  series: PropTypes.array, // 纵轴数据（[{name:'',data:[], yAxisIndex:'默认是0',type:'默认是type中定义的类型'},...]）
  type: PropTypes.oneOf([
    // 图表类型（优先级低于series中定义的type）
    'line', // 折线图
    'bar', // 柱状图
    'area', // 面积图
    'point', // 点状图（不是散点图，是折线图去掉线条，只留点）
    'lineStack', // 线性堆叠图
    'areaStack', // 面积堆叠图
    'barStack', // 柱状堆叠图
  ]),
  height: PropTypes.oneOfType([
    // 图表高度（百分比、数值、auto(自动根据图例数量计算高度)）
    PropTypes.string,
    PropTypes.number,
  ]),
  width: PropTypes.oneOfType([
    // 图表宽度（百分比或数值）
    PropTypes.string,
    PropTypes.number,
  ]),
  dataZoom: PropTypes.oneOfType([
    // 是否有横向滚动轴（{startValue: 0,endValue: 5}）
    PropTypes.bool,
    PropTypes.object,
  ]),
  colors: PropTypes.array, // 图表颜色
  title: PropTypes.string, // 标题
  toolTipFormat: PropTypes.func, // 提示框内容显示格式处理
  toolTipDataFormat: PropTypes.array, // 数据在提示框中显示的格式（与所在纵轴位置一致，从左向右，每一项用func表示，如[value=>parseInt(value)}, value=>value+'%',...]，，没有的项用空位表示）
  yAxisUnit: PropTypes.array, // 纵轴上的单位（从左向右，每一项用字符串数据表示，没有的项用空位表示）
  yAxisFormat: PropTypes.array, // 纵轴数据显示格式处理（从左向右，每一项用func表示，如[value=>parseInt(value)}, value=>value+'%',...]，，没有的项用空位表示）
  boundaryGap: PropTypes.bool, // 坐标轴两边留白策略
  yAxisRange: PropTypes.array, // 纵轴数据展示的min与max（从左向右，每一项用数组表示，如[[min,max],[min,max],...]，，没有的项用空位表示）
  lableRotate: PropTypes.number, // 横轴字体旋转角度
  isAbbreviate: PropTypes.bool, // 横轴是否缩略展示（仅展示前5个字）
  showBorder: PropTypes.bool, // 是否显示图形外层边框
  hasYAxisPosi: PropTypes.bool, // 标记是否在图例中特意标明对应的数据是左轴还是右轴
  gridLeft: PropTypes.number, // 左轴距离左侧的距离
  gridRight: PropTypes.number, // 右轴距离右侧的距离
  seriesLabelDataFormat: PropTypes.array, // 图形上的文本标签格式，若设置则展示标签，若不设置，则不显示标签([params=>params.data,,params=>params.data+'%',...])，默认数据量超过15条不展示
  percentStyle: PropTypes.array, // 纵轴上若按百分比展示，有一套小数点位数的规则(对需要按百分比规则展示的列号，对应的数组位置处设置true，不需要设置的空置或设false)
  // 该设置优先级低于yAxisFormat的优先级
  markArea: PropTypes.array, // 区域样式设置[{range:[],color:''},{range:[],color:''},...]
  barMaxWidth: PropTypes.number, // 仅type为bar或barstack时有效，设置柱状图宽度
  legentAbbreviate: PropTypes.bool, // 图例是否缩略展示（仅展示前5个字）（优先级高于hasYAxisPosi）
  debtAndProfit: PropTypes.bool, // 收益&负债类型的样式（红绿）
  click: PropTypes.func, // 点击事件
  mouseOver: PropTypes.func, // 悬浮事件
  mouseOut: PropTypes.func, // 悬浮离开事件
  isShowLegent: PropTypes.bool, // 是否展示图例
  isShowTooltip: PropTypes.bool, // 是否展示tooltip
  legendSelect: PropTypes.object, // 初始不选中的图例
  thousandthStyle: PropTypes.bool, // tooltip中的数值是否千分位展示
  tooltipValueFix: PropTypes.number, // tooltip中的数值的精度，
  legendType: PropTypes.string, // 图例的类型。'plain'：普通图例。'scroll'：可滚动翻页的图例。当图例数量较多时可以使用。
  cordonConfig: PropTypes.object, // 警戒线配置 cordonValue: 警戒线的标注值
  isMarkPoint: PropTypes.bool, // 是否显示最大最小值图标
  axisLabelFormatter: PropTypes.func, // x轴的字Formatter函数
  axisLabelMargin: PropTypes.number, // x轴的字距离x轴的距离 默认6
  legendBottom: PropTypes.number, // 图例距离底的距离 默认15
  isResponsiveHeight: PropTypes.bool, // 是否是响应式height
};

export default XYAxisChartsC;
